package org.example.JVM.Proxy.JDK;


import org.example.JVM.ByteCode.Util.ByteCodeUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description: 手动实现JDK动态代理，InvokationHandler使用JDK提供的
 * @author: farprt
 * @create: 2022-11-18 19:44
 **/
public class MyProxy {

    private final static AtomicInteger PROXY_CNT = new AtomicInteger(0);
    protected InvocationHandler h;

    private MyProxy() {

    }

    protected MyProxy(InvocationHandler h) {
        this.h = h;
    }

    /**
     * @param interfaces
     * @param h
     * @return: {@link Objects}
     * @Author: farprt
     * @date: 2022/12/4 20:11
     * @description: 创建一个代理类，并使用类加载器加载这个代理类，最后通过反射创建一个代理类实例。类加载器用自定义类加载器
     */
    public static Object newProxyInstance(Class<?>[] interfaces, InvocationHandler h) throws Exception {
        String proxyClassName = "org/example/JVM/Proxy/$Proxy" + PROXY_CNT.getAndIncrement();
        // 创建代理类
        byte[] proxyClassByteCode = MyProxyFactory.createProxyClass(proxyClassName, interfaces);
        // 加载代理类
        Class<?> proxyClass = ByteCodeUtils.loadClass(proxyClassName, proxyClassByteCode);
        // 反射创建代理类
        Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
        return constructor.newInstance(h);
    }
}